import { ethers } from 'ethers'

/**
 * 解析合约错误，提取 revert 原因
 * @param {Object} error - 错误对象
 * @returns {string} 解析后的错误消息
 */
const parseContractError = (error) => {
    // 错误原因映射
    const errorMap = {
        not_member: "非有效地址",
        UNAUTHORIZED: "无权限：您没有权限执行此操作",
        INSUFFICIENT_BALANCE: "余额不足：账户余额不足以完成此操作",
        INVALID_ADDRESS: "无效地址：提供的地址格式不正确",
        TRANSACTION_FAILED: "交易失败：交易执行失败，请重试",
    };

    // 尝试解析 ABI 编码的 revert 错误
    const tryDecodeRevertReason = (data) => {
        if (!data || typeof data !== 'string') return null;

        // Error(string) 的 selector 是 0x08c379a0
        const errorSelector = '0x08c379a0';

        // 检查是否包含错误 selector
        if (data.includes(errorSelector)) {
            try {
                // 找到 selector 的位置
                const selectorIndex = data.indexOf(errorSelector);

                // 提取 selector 之后的所有数据
                let encodedData = data.substring(selectorIndex);

                // 确保以 0x 开头
                if (!encodedData.startsWith('0x')) {
                    encodedData = '0x' + encodedData;
                }

                // 去掉 selector，获取 ABI 编码的参数部分
                const dataWithoutSelector = '0x' + encodedData.substring(errorSelector.length);

                // 使用 ethers 解码 Error(string) 的参数部分
                // 数据格式：offset (32 bytes) + length (32 bytes) + string data
                try {
                    const decoded = ethers.utils.defaultAbiCoder.decode(['string'], dataWithoutSelector);
                    if (decoded && decoded[0]) {
                        return decoded[0];
                    }
                } catch (decodeError) {
                    // 如果 defaultAbiCoder 失败，尝试手动解析
                    // ABI 编码格式：offset (64 hex chars) + length (64 hex chars) + data
                    // dataPart 是去掉 selector 后的数据（不包含 0x 前缀）
                    const dataPart = encodedData.substring(errorSelector.length);
                    // 去掉可能的 0x 前缀（如果存在）
                    const cleanDataPart = dataPart.startsWith('0x') ? dataPart.substring(2) : dataPart;

                    if (cleanDataPart.length >= 128) {
                        // 跳过 offset (前64个字符)，读取 length (接下来64个字符)
                        const lengthHex = cleanDataPart.substring(64, 128);
                        const length = parseInt(lengthHex, 16);

                        if (length > 0 && cleanDataPart.length >= 128 + length * 2) {
                            // 读取字符串数据（从128个字符后开始，长度为 length * 2）
                            const stringHex = cleanDataPart.substring(128, 128 + length * 2);
                            try {
                                const decodedString = ethers.utils.toUtf8String('0x' + stringHex);
                                return decodedString;
                            } catch (utf8Error) {
                                // UTF-8 解码失败
                                console.warn('Failed to decode UTF-8:', utf8Error);
                            }
                        }
                    }
                }
            } catch (e) {
                // 解码失败，继续尝试其他方法
                console.warn('Failed to decode revert reason:', e);
            }
        }

        return null;
    };

    // 从错误对象中提取 revert 数据
    const extractRevertData = (err) => {
        // 尝试多个可能的位置
        if (err?.data?.originalError?.data) {
            return err.data.originalError.data;
        }
        if (err?.error?.data) {
            return err.error.data;
        }
        if (err?.data) {
            return err.data;
        }
        if (err?.reason) {
            // reason 可能包含完整的错误信息，尝试提取其中的 hex 数据
            const match = err.reason.match(/0x[0-9a-fA-F]+/);
            if (match) {
                return match[0];
            }
        }
        return null;
    };

    // 尝试解析 revert 原因
    const revertData = extractRevertData(error);
    if (revertData) {
        const decodedReason = tryDecodeRevertReason(revertData);
        if (decodedReason) {
            // 检查是否是已知错误类型
            for (const [key, message] of Object.entries(errorMap)) {
                if (decodedReason.toUpperCase().includes(key)) {
                    return message;
                }
            }
            // 返回解码后的错误信息
            return `交易失败：${decodedReason}`;
        }
    }
			
    // 尝试从 error.reason 中提取（可能已经包含错误消息）
    if (error && error.reason) {
        // 检查 reason 中是否已经包含可读的错误消息
        if (error.reason.includes('execution reverted:')) {
            // 尝试提取 execution reverted 后面的错误消息
            // 格式：execution reverted: BEP20: transfer amount exceeds balance: 0x08c379a0...
            // 我们需要提取冒号后面、hex 数据前面的部分
            const parts = error.reason.split('execution reverted:');
            if (parts.length > 1) {
                let reasonPart = parts[1].trim();
                // 如果包含 hex 数据（以 0x 开头），提取之前的部分
                const hexIndex = reasonPart.search(/\s+0x[0-9a-fA-F]{10,}/);
                if (hexIndex > 0) {
                    reasonPart = reasonPart.substring(0, hexIndex).trim();
                }
                // 移除末尾可能的冒号
                reasonPart = reasonPart.replace(/:\s*$/, '');

                if (reasonPart) {
                    // 检查是否是已知错误类型
                    for (const [key, message] of Object.entries(errorMap)) {
                        if (reasonPart.includes(key)) {
                            return message;
                        }
                    }
                    return `交易失败：${reasonPart}`;
                }
            }
        }

        // 检查是否包含已知错误
        for (const [key, message] of Object.entries(errorMap)) {
            if (error.reason.includes(key)) {
                return message;
            }
        }
    }

    // 尝试从 error.message 中提取
    if (error && error.message) {
        // 检查是否包含 revert 信息
        if (error.message.includes('execution reverted:')) {
            const parts = error.message.split('execution reverted:');
            if (parts.length > 1) {
                let reasonPart = parts[1].trim();
                // 如果包含 hex 数据（以 0x 开头），提取之前的部分
                const hexIndex = reasonPart.search(/\s+0x[0-9a-fA-F]{10,}/);
                if (hexIndex > 0) {
                    reasonPart = reasonPart.substring(0, hexIndex).trim();
                }
                // 移除末尾可能的冒号
                reasonPart = reasonPart.replace(/:\s*$/, '');

                if (reasonPart) {
                    for (const [key, message] of Object.entries(errorMap)) {
                        if (reasonPart.toUpperCase().includes(key)) {
                            return message;
                        }
                    }
                    return `交易失败：${reasonPart}`;
                }
            }
        }

        // 检查是否包含已知错误
        for (const [key, message] of Object.entries(errorMap)) {
            if (error.message.includes(key)) {
                return message;
            }
        }

        // 如果是用户拒绝连接
        if (error.message.includes("用户拒绝") || error.message.includes("rejected") || error.message.includes("User denied")) {
            return "操作已取消：您取消了交易";
        }

        // 如果是网络错误
        if (error.message.includes("network") || error.message.includes("网络")) {
            return "网络错误：请检查网络连接";
        }

        // 如果是 gas 估算错误，但已经包含 revert 信息
        if (error.message.includes("UNPREDICTABLE_GAS_LIMIT") || error.message.includes("cannot estimate gas")) {
            // 尝试从 reason 中提取
            if (error.reason && error.reason.includes('execution reverted:')) {
                const parts = error.reason.split('execution reverted:');
                if (parts.length > 1) {
                    let reasonPart = parts[1].trim();
                    // 如果包含 hex 数据，提取之前的部分
                    const hexIndex = reasonPart.search(/\s+0x[0-9a-fA-F]{10,}/);
                    if (hexIndex > 0) {
                        reasonPart = reasonPart.substring(0, hexIndex).trim();
                    }
                    reasonPart = reasonPart.replace(/:\s*$/, '');
                    if (reasonPart) {
                        return `交易失败：${reasonPart}`;
                    }
                }
            }
            return "交易失败：交易可能失败，请检查余额和授权";
        }
    }

    // 尝试从 error.code 判断
    if (error && error.code) {
        if (error.code === 4001 || error.code === 'ACTION_REJECTED') {
            return "操作已取消：您取消了交易";
        }
    }

    // 默认错误信息
    return `上链失败：${error?.message || error?.reason || '未知错误'}`;
};

export default parseContractError;

